const Shell = imports.gi.Shell;
const GnomeSession = imports.misc.gnomeSession;
-const Main = imports.ui.main;
+const LoginManager = imports.misc.loginManager;
const ModalDialog = imports.ui.modalDialog;
const Tweener = imports.ui.tweener;
const UserWidget = imports.ui.userWidget;
2 /* GSM_SHELL_END_SESSION_DIALOG_TYPE_RESTART */: restartDialogContent
};
+const MAX_USERS_IN_SESSION_DIALOG = 5;
+
+const LogindSessionIface = <interface name='org.freedesktop.login1.Session'>
+ <property name="Id" type="s" access="read"/>
+ <property name="Remote" type="b" access="read"/>
+ <property name="Class" type="s" access="read"/>
+ <property name="Type" type="s" access="read"/>
+ <property name="State" type="s" access="read"/>
+</interface>;
+
+const LogindSession = Gio.DBusProxy.makeProxyWrapper(LogindSessionIface);
+
function findAppFromInhibitor(inhibitor) {
let desktopFile;
try {
const ListItem = new Lang.Class({
Name: 'ListItem',
- _init: function(app, reason) {
- this._app = app;
- this._reason = reason;
-
- if (this._reason == null)
- this._reason = '';
-
- let layout = new St.BoxLayout({ vertical: false});
+ _init: function(icon, name, description) {
+ let layout = new St.BoxLayout({ vertical: false });
this.actor = new St.Bin({ style_class: 'end-session-dialog-app-list-item',
- can_focus: true,
- child: layout,
- x_align: St.Align.START,
- x_fill: true });
-
- this._icon = this._app.create_icon_texture(_ITEM_ICON_SIZE);
+ can_focus: true,
+ child: layout,
+ x_align: St.Align.START,
+ x_fill: true });
let iconBin = new St.Bin({ style_class: 'end-session-dialog-app-list-item-icon',
- child: this._icon });
+ child: icon });
layout.add(iconBin);
let textLayout = new St.BoxLayout({ style_class: 'end-session-dialog-app-list-item-text-box',
- vertical: true });
+ vertical: true });
layout.add(textLayout);
- this._nameLabel = new St.Label({ text: this._app.get_name(),
- style_class: 'end-session-dialog-app-list-item-name' });
- textLayout.add(this._nameLabel,
- { expand: false,
- x_fill: true });
-
- this._descriptionLabel = new St.Label({ text: this._reason,
- style_class: 'end-session-dialog-app-list-item-description' });
- this.actor.label_actor = this._nameLabel;
- textLayout.add(this._descriptionLabel,
- { expand: true,
- x_fill: true });
+ let nameLabel = new St.Label({ text: name,
+ style_class: 'end-session-dialog-app-list-item-name' });
+ textLayout.add(nameLabel, { expand: false, x_fill: true });
+ this.actor.label_actor = nameLabel;
+
+ if (description) {
+ let descriptionLabel = new St.Label({ text: description,
+ style_class: 'end-session-dialog-app-list-item-description' });
+ textLayout.add(descriptionLabel, { expand: true, x_fill: true });
+ }
},
});
this.parent({ styleClass: 'end-session-dialog',
destroyOnClose: false });
- this._user = AccountsService.UserManager.get_default().get_user(GLib.get_user_name());
+ this._loginManager = LoginManager.getLoginManager();
+ this._userManager = AccountsService.UserManager.get_default();
+ this._user = this._userManager.get_user(GLib.get_user_name());
this._secondsLeft = 0;
this._totalSecondsToStayOpen = 0;
this._inhibitors = [];
+ this._sessions = [];
this.connect('destroy',
Lang.bind(this, this._onDestroy));
this._user.disconnect(this._userChangedId);
},
+ _hasInhibitors: function() {
+ return (this._inhibitors.length > 0) || (this._sessions.length > 0);
+ },
+
_updateDescription: function() {
if (this.state != ModalDialog.State.OPENING &&
this.state != ModalDialog.State.OPENED)
let subject = dialogContent.subject;
let description;
- if (this._inhibitors.length > 0) {
+ if (this._hasInhibitors()) {
this._stopTimer();
description = dialogContent.inhibitedDescription;
- } else if (this._secondsLeft > 0 && this._inhibitors.length == 0) {
+ } else if (this._secondsLeft > 0) {
let displayTime = _roundSecondsToInterval(this._totalSecondsToStayOpen,
this._secondsLeft,
10);
},
_onOpened: function() {
- if (this._inhibitors.length == 0)
+ if (!this._hasInhibitors())
this._startTimer();
},
if (app) {
let [reason] = inhibitor.GetReasonSync();
- let item = new ListItem(app, reason);
+ let item = new ListItem(app.create_icon_texture(_ITEM_ICON_SIZE), app.get_name(), reason);
this._applicationList.add(item.actor, { x_fill: true });
this._stopTimer();
} else {
this._updateContent();
},
+ _loadSessions: function() {
+ this._loginManager.listSessions(Lang.bind(this, function(result) {
+ let n = 0;
+ for (let i = 0; i < result.length; i++) {
+ let[id, uid, userName, seat, sessionPath] = result[i];
+ let proxy = new LogindSession(Gio.DBus.system, 'org.freedesktop.login1', sessionPath);
+
+ if (proxy.Class != 'user')
+ continue;
+
+ if (proxy.State == 'closing')
+ continue;
+
+ if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
+ continue;
+
+ let session = { user: this._userManager.get_user(userName),
+ username: userName,
+ type: proxy.Type,
+ remote: proxy.Remote };
+ this._sessions.push(session);
+
+ let avatar = new UserWidget.Avatar(session.user, { iconSize: _ITEM_ICON_SIZE });
+ avatar.update();
+
+ let userLabel = session.user.get_real_name() ? session.user.get_real_name() : userName;
+ let userLabelText;
+
+ if (session.remote)
+ /* Translators: Remote here refers to a remote session, like a ssh login */
+ userLabelText = _("%s (remote)").format(userName);
+ else if (session.type == "tty")
+ /* Translators: Console here refers to a tty like a VT console */
+ userLabelText = _("%s (console)").format(userName);
+ else
+ userLabelText = userName;
+
+ let item = new ListItem(avatar.actor, userLabelText);
+
+ // XXX -- put them in their own inhibitor section
+ this._applicationList.add(item.actor, { x_fill: true });
+
+ // limit the number of entries
+ n++;
+ if (n == MAX_USERS_IN_SESSION_DIALOG)
+ break;
+ }
+
+ if (n > 0)
+ this._stopTimer();
+ }));
+ },
+
OpenAsync: function(parameters, invocation) {
let [type, timestamp, totalSecondsToStayOpen, inhibitorObjectPaths] = parameters;
this._totalSecondsToStayOpen = totalSecondsToStayOpen;
this._inhibitors.push(inhibitor);
}
+ this._loadSessions();
+
this._updateButtons();
if (!this.open(timestamp)) {
const Gdm = imports.gi.Gdm;
const Gio = imports.gi.Gio;
const GLib = imports.gi.GLib;
-const Gtk = imports.gi.Gtk;
const Lang = imports.lang;
const Shell = imports.gi.Shell;
const St = imports.gi.St;
-const Clutter = imports.gi.Clutter;
const BoxPointer = imports.ui.boxpointer;
const GnomeSession = imports.misc.gnomeSession;
const LoginManager = imports.misc.loginManager;
const Main = imports.ui.main;
-const ModalDialog = imports.ui.modalDialog;
const PanelMenu = imports.ui.panelMenu;
const PopupMenu = imports.ui.popupMenu;
-const Util = imports.misc.util;
-const UserWidget = imports.ui.userWidget;
const LOCKDOWN_SCHEMA = 'org.gnome.desktop.lockdown';
const SCREENSAVER_SCHEMA = 'org.gnome.desktop.screensaver';
const DISABLE_LOG_OUT_KEY = 'disable-log-out';
const ALWAYS_SHOW_LOG_OUT_KEY = 'always-show-log-out';
-const MAX_USERS_IN_SESSION_DIALOG = 5;
-
-const SystemdLoginSessionIface = <interface name='org.freedesktop.login1.Session'>
- <property name="Id" type="s" access="read"/>
- <property name="Remote" type="b" access="read"/>
- <property name="Class" type="s" access="read"/>
- <property name="Type" type="s" access="read"/>
- <property name="State" type="s" access="read"/>
-</interface>;
-
-const SystemdLoginSession = Gio.DBusProxy.makeProxyWrapper(SystemdLoginSessionIface);
-
const Indicator = new Lang.Class({
Name: 'SystemIndicator',
Extends: PanelMenu.SystemIndicator,
this._session = new GnomeSession.SessionManager();
this._haveShutdown = true;
- this._loginManager = LoginManager.getLoginManager();
this._userManager = AccountsService.UserManager.get_default();
this._user = this._userManager.get_user(GLib.get_user_name());
this._session.LogoutRemote(0);
},
- _openSessionWarnDialog: function(sessions) {
- let dialog = new ModalDialog.ModalDialog();
- let subjectLabel = new St.Label({ style_class: 'end-session-dialog-subject',
- text: _("Other users are logged in.") });
- dialog.contentLayout.add(subjectLabel, { y_fill: true,
- y_align: St.Align.START });
-
- let descriptionLabel = new St.Label({ style_class: 'end-session-dialog-description'});
- descriptionLabel.set_text(_("Shutting down might cause them to lose unsaved work."));
- descriptionLabel.clutter_text.line_wrap = true;
- dialog.contentLayout.add(descriptionLabel, { x_fill: true,
- y_fill: true,
- y_align: St.Align.START });
-
- let scrollView = new St.ScrollView({ style_class: 'end-session-dialog-app-list' });
- scrollView.add_style_class_name('vfade');
- scrollView.set_policy(Gtk.PolicyType.NEVER, Gtk.PolicyType.AUTOMATIC);
- dialog.contentLayout.add(scrollView, { x_fill: true, y_fill: true });
-
- let userList = new St.BoxLayout({ vertical: true });
- scrollView.add_actor(userList);
-
- for (let i = 0; i < sessions.length; i++) {
- let session = sessions[i];
- let userEntry = new St.BoxLayout({ style_class: 'login-dialog-user-list-item',
- vertical: false });
- let avatar = new UserWidget.Avatar(session.user);
- avatar.update();
- userEntry.add(avatar.actor);
-
- let userLabelText = "";;
- let userName = session.user.get_real_name() ?
- session.user.get_real_name() : session.username;
-
- if (session.info.remote)
- /* Translators: Remote here refers to a remote session, like a ssh login */
- userLabelText = _("%s (remote)").format(userName);
- else if (session.info.type == "tty")
- /* Translators: Console here refers to a tty like a VT console */
- userLabelText = _("%s (console)").format(userName);
- else
- userLabelText = userName;
-
- let textLayout = new St.BoxLayout({ style_class: 'login-dialog-user-list-item-text-box',
- vertical: true });
- textLayout.add(new St.Label({ text: userLabelText }),
- { y_fill: false,
- y_align: St.Align.MIDDLE,
- expand: true });
- userEntry.add(textLayout, { expand: true });
- userList.add(userEntry, { x_fill: true });
- }
-
- let cancelButton = { label: _("Cancel"),
- action: function() { dialog.close(); },
- key: Clutter.Escape };
-
- let powerOffButton = { label: _("Power Off"), action: Lang.bind(this, function() {
- dialog.close();
- this._session.ShutdownRemote();
- }), default: true };
-
- dialog.setButtons([cancelButton, powerOffButton]);
-
- dialog.open();
- },
-
_onPowerOffClicked: function() {
this.menu.itemActivated();
Main.overview.hide();
- this._loginManager.listSessions(Lang.bind(this, function(result) {
- let sessions = [];
- let n = 0;
- for (let i = 0; i < result.length; i++) {
- let[id, uid, userName, seat, sessionPath] = result[i];
- let proxy = new SystemdLoginSession(Gio.DBus.system,
- 'org.freedesktop.login1',
- sessionPath);
-
- if (proxy.Class != 'user')
- continue;
-
- if (proxy.State == 'closing')
- continue;
-
- if (proxy.Id == GLib.getenv('XDG_SESSION_ID'))
- continue;
-
- sessions.push({ user: this._userManager.get_user(userName),
- username: userName,
- info: { type: proxy.Type,
- remote: proxy.Remote }
- });
-
- // limit the number of entries
- n++;
- if (n == MAX_USERS_IN_SESSION_DIALOG)
- break;
- }
-
- if (n != 0)
- this._openSessionWarnDialog(sessions);
- else
- this._session.ShutdownRemote();
- }));
+ this._session.ShutdownRemote(0);
}
});